#pragma once

/**
 * wait_for_true = TRUE:
 * If boolean is true, the event is set - not waiting,
 * If boolean is false, the event is reset - waiting.
 * 
 * wait_for_true = FALSE:
 * If boolean is true, the event is reset - waiting,
 * If boolean is false, the event is set - not waiting.
 */
class eventable_bool
{
public:
	eventable_bool()
	{ 
		_wait_for_true = ::CreateEvent(NULL, TRUE, FALSE, NULL);
		_wait_for_false = ::CreateEvent(NULL, TRUE, TRUE, NULL);
	}

	~eventable_bool() // removed until thread_state uses as shared_ptr 
	{ 
		::CloseHandle(_wait_for_true);
		::CloseHandle(_wait_for_false);

		_wait_for_true = nullptr;
		_wait_for_false = nullptr;
	}

	virtual void operator = (bool val)
	{
		_bool = val;

		if(val)
		{
			if(!::ResetEvent(_wait_for_false))
			{
				printf("SetEvent Failed! 0x%x\r\n", ::GetLastError());
				ExitProcess(1);
			}

			if(!::SetEvent(_wait_for_true))
			{
				printf("SetEvent Failed! 0x%x\r\n", ::GetLastError());
				ExitProcess(1);
			}
		}
		else
		{
			if(!::ResetEvent(_wait_for_true))
			{
				printf("SetEvent Failed! 0x%x\r\n", ::GetLastError());
				ExitProcess(1);
			}

			if(!::SetEvent(_wait_for_false))
			{
				printf("SetEvent Failed! 0x%x\r\n", ::GetLastError());
				ExitProcess(1);
			}
		}
	}

	operator bool(){ return _bool; }

	inline HANDLE wait_for(bool val){ return val ? _wait_for_true : _wait_for_false; }

	HANDLE	_wait_for_true	 = nullptr;
	HANDLE	_wait_for_false	 = nullptr;
	bool	_bool			 = false;
	std::mutex	_change_val_lock;
};


class waiting_group_bool : public eventable_bool
{
public:
	waiting_group_bool():eventable_bool(){}

	virtual void operator = (bool val)
	{
		/*
		short val_int = (val ? 1 : 0);

//		std::unique_lock<std::mutex> ul(_change_val_lock);
		
		if(tester != 2 && tester != val_int)
		{
			printf("Something is Wrong!");
			ExitProcess(1);
		}

		tester = val_int;
		*/
		eventable_bool::operator =(val);

		//tester = 2;
	}

	short tester = 2;
};